package ar.edu.itba.pod.legajo48240.pruebas.cristian;

import java.util.Properties;

import org.apache.log4j.Logger;
import org.joda.time.Duration;

import ar.edu.itba.node.NodeInformation;
import ar.edu.itba.node.api.NodeStatistics;
import ar.edu.itba.pod.agent.market.AgentState;
import ar.edu.itba.pod.agent.market.Consumer;
import ar.edu.itba.pod.agent.market.Market;
import ar.edu.itba.pod.agent.market.Producer;
import ar.edu.itba.pod.agent.market.Resource;
import ar.edu.itba.pod.legajo48240.model.Host;
import ar.edu.itba.pod.legajo48240.utils.Net;
import ar.edu.itba.pod.thread.CleanableThread;

public class PruebaCristian implements Runnable {

	static Logger LOGGER = Logger.getLogger(PruebaCristian.class);

	static Properties constants = new Properties();

	public static void main(String[] args) {
		new PruebaCristian().run();
	}

	@Override
	public void run() {

		/**
		 *                 ATENCION !
		 *              ===============
		 *              Cambiar el parametro IP de la maquina virtual !
		 *              en run configuration
		 */

		String host = "10.6.0.30";
//		String host = "192.168.1.103"; 
		
		
		boolean WITH_EVENTS = true;
		boolean START_SIMULATION = true;

		int SECONDS=1;

		Host hostA = new Host(host, 7000, "10.6.0.30:7000"); //A
		Host hostB = new Host(host, 7001, "10.6.0.30:7001"); //B

		showStatistics(hostA);


		try {
			hostA.network().createGroup();
			try {

				Resource gold = new Resource("Mineral", "Gold");
				Resource copper = new Resource("Mineral", "Copper");
				Resource steel = new Resource("Alloy", "Steel");

				for (int i = 0; i < 2; i++) {
					hostA.simulation().add(new Producer( "gold mine de A" + i, gold, Duration.standardDays(2), 1));
					hostA.simulation().add(new Consumer( "gold consumer de A" + i, gold, Duration.standardDays(3), 1));
				}
				
				LOGGER.info("conecta B");
				try { Thread.sleep(SECONDS*1000); } catch (InterruptedException ignore) {}
				hostB.network().connectToGroup(hostA.host(), hostA.port());

				for (int i = 0; i < 1; i++) {
					hostB.simulation().add(new Producer( "gold mine de B" + i, gold, Duration.standardDays(2), 1));
					hostB.simulation().add(new Consumer( "gold consumer de B" + i, gold, Duration.standardDays(3), 1));
				}

				try { Thread.sleep(1*1000); } catch (InterruptedException ignore) {}

				LOGGER.info("CLUSTER CREATED SUCCESFULLY -- Coordinator: " + hostA.getCoordinator() +" in " + hostA.id());
				LOGGER.info("CLUSTER CREATED SUCCESFULLY -- Coordinator: " + hostB.getCoordinator() +" in " + hostB.id());


				if(WITH_EVENTS){

					LOGGER.info("cargo agentes");
					hostA.simulation().add(new Market( "gold market A", gold));
					
					LOGGER.info("listo agentes");
					try { Thread.sleep(1*1000); } catch (InterruptedException ignore) {}

					if(START_SIMULATION){
						LOGGER.info("SIMULATION >> Starting ........... .....................................\n");
						hostA.simulation().start(Duration.standardDays(10));
						hostB.simulation().start(Duration.standardDays(10));
					}else{
						LOGGER.info("SIMULATION DISABLED");
					}

					
					try { Thread.sleep(20*1000); } catch (InterruptedException ignore) {}
//					hostA.shutdown();

				}

			} catch (Exception e) {
				LOGGER.error("CLUSTER Network Connection problem");
				e.printStackTrace();

			} 
		}catch (Exception e) {
			LOGGER.error("CLUSTER NOT CREATED ! Maybe Already Started");
			e.printStackTrace();
		}finally{
//			hostA.finish();
//			hostB.finish();
		}
	}

	private void showStatistics(final Host host) {

		CleanableThread statistics = new CleanableThread("stats") {
			@Override
			public void run() {
				super.run();
				while(true){
					try {
						Thread.sleep(20*1000);
						for(NodeInformation node:host.network().connectedNodes()){
							NodeStatistics stats=Net.getStatistic(node).getNodeStatistics();
							
							LOGGER.info("STATS OF : " + node.id() + " agents: " + stats.getNumberOfAgents());
							for(AgentState as:stats.getAgentState()){
								LOGGER.info(as);
							}
						}
					} catch (Exception ignore) {	}
				}
			}
		};
		statistics.start();
	} 
}